package com.simple.simple_view.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.simple.simple_view.domain.ResponseResult;
import com.simple.simple_view.domain.dto.VideoDto;
import com.simple.simple_view.domain.entity.User;
import com.simple.simple_view.domain.entity.Video;
import com.simple.simple_view.domain.enums.AppHttpCodeEnum;
import com.simple.simple_view.domain.system.RedisSystemParam;
import com.simple.simple_view.domain.system.SystemParam;
import com.simple.simple_view.domain.vo.VideoInfo;
import com.simple.simple_view.exception.SystemException;
import com.simple.simple_view.mapper.VideoMapper;
import com.simple.simple_view.service.OSSUploadService;
import com.simple.simple_view.service.UserService;
import com.simple.simple_view.service.VideoService;
import com.simple.simple_view.utils.PathUtil;
import com.simple.simple_view.utils.RedisCache;
import com.simple.simple_view.utils.SecurityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 视频表(Video)表服务实现类
 *
 * @author makejava
 * @since 2023-10-26 16:08:18
 */
@Component
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {
    @Resource
    OSSUploadService ossUploadService;
    @Resource
    RedisCache redisCache;
    @Resource
    UserService userService;

    @Override
    public void uploadFile(MultipartFile file) throws IOException {

    }

    @Override
    public ResponseResult uploadVideo(VideoDto videoDto) throws Exception {
        videoDto.setStatus(SystemParam.STATUS_AUDIT);
        MultipartFile videoFile = videoDto.getVideoFile();
        String fileName = videoFile.getOriginalFilename();
        if (fileName == null) {
            //TODO
            log.error(videoDto.toString(), new SystemException(AppHttpCodeEnum.FILE_TYPE_ERROR));
            return ResponseResult.errorResult(AppHttpCodeEnum.FILE_TYPE_ERROR);
        }
        String fileDir = PathUtil.generateFileDir(SystemParam.FILE_TYPE_VIDEO, fileName);
        Video video = new Video();
        video.setUserId(SecurityUtil.getUserId());
        BeanUtils.copyProperties(videoDto, video);
        boolean uploadVideo = save(video);
        if (!uploadVideo) return ResponseResult.errorResult(AppHttpCodeEnum.USER_UPDATE_ERROR);
        ossUploadService.upload(videoFile.getInputStream(), fileDir)
                .addCallback(
                        result -> {
                            video.setUrl(result);
                            video.setStatus(SystemParam.STATUS_NORMAL);
                            updateById(video);
                        }, ex -> {
                            //TODO 上传视频失败
                            log.error(ex.getMessage(), ex);
                        }
                );
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getVideoPage(int currentPage, int pageSize) {
        Page<Video> videoPage = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Video> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Video::getCreateTime);
        Page<Video> page = page(videoPage, wrapper);
        redisCache.batchSetObject(page.getRecords());
        return ResponseResult.okResult(page);
    }

    @Override
    public ResponseResult getVideoInfo(int videoId) {
        JSONObject videoObj = redisCache.getCacheObject(RedisSystemParam.VIDEO_PREFIX +videoId);
        Video video;
        if (videoObj != null) video=videoObj.toJavaObject(Video.class);
        else {
            video = getById(videoId);
            redisCache.setCacheObject(RedisSystemParam.VIDEO_PREFIX + videoId,
                    video,
                    RedisSystemParam.VIDEO_EXPIRES + new Random().nextInt(RedisSystemParam.VIDEO_EXPIRES),
                    TimeUnit.SECONDS);
        }
        JSONObject userObj = redisCache.getCacheObject(RedisSystemParam.USER_PREFIX + video.getUserId());
        User user;
        if (userObj != null) user=userObj.toJavaObject(User.class);
        else {
            user = userService.getById(video.getUserId());
            redisCache.setCacheObject(RedisSystemParam.USER_PREFIX + user.getId(),
                    user,
                    RedisSystemParam.USER_EXPIRES + new Random().nextInt(RedisSystemParam.USER_EXPIRES),
                    TimeUnit.SECONDS);
        }
        VideoInfo videoInfo = new VideoInfo();
        BeanUtils.copyProperties(video, videoInfo);
        BeanUtils.copyProperties(user, videoInfo);
        return ResponseResult.okResult(videoInfo);
    }
}
